package com.ht.modules.system.online.cgform.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ht.entity.Result;
import com.ht.modules.system.online.cgform.enhance.CgformEnhanceJavaInter;
import com.ht.modules.system.online.cgform.entity.*;
import com.ht.modules.system.online.cgform.mapper.*;
import com.ht.modules.system.online.cgform.model.OnlCgformModel;
import com.ht.modules.system.online.cgform.model.OnlGenerateModel;
import com.ht.modules.system.online.cgform.service.IOnlCgformFieldService;
import com.ht.modules.system.online.cgform.service.IOnlCgformHeadService;
import com.ht.modules.system.online.cgform.service.IOnlCgformIndexService;
import com.ht.modules.system.online.cgform.util.CgformUtil;
import com.ht.modules.system.online.codegenerate.database.DbReadTableUtil;
import com.ht.modules.system.online.codegenerate.generate.impl.CodeGenerateOne;
import com.ht.modules.system.online.codegenerate.generate.pojo.ColumnVo;
import com.ht.modules.system.online.codegenerate.generate.pojo.TableVo;
import com.ht.modules.system.online.config.exception.BusinessException;
import com.ht.modules.system.online.config.exception.DBException;
import com.ht.modules.system.online.config.model.CgformConfigModel;
import com.ht.modules.system.online.config.model.DataBaseConfig;
import com.ht.modules.system.online.config.service.DbTableHandleI;
import com.ht.modules.system.online.config.util.DbTableProcess;
import com.ht.modules.system.online.config.util.DbTableUtil;
import com.ht.utils.MyClassLoader;
import com.ht.utils.SpringContextUtils;
import com.ht.utils.UUIDGenerator;
import com.ht.utils.oConvertUtils;
import freemarker.template.TemplateException;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.hibernate.HibernateException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.sql.SQLException;
import java.util.*;

@Slf4j
@Service
public class OnlCgformHeadServiceImpl extends ServiceImpl<OnlCgformHeadMapper, OnlCgformHead> implements IOnlCgformHeadService {
    @Autowired
    private IOnlCgformFieldService fieldService;
    @Autowired
    private IOnlCgformIndexService indexService;
    @Resource
    private OnlCgformEnhanceJsMapper onlCgformEnhanceJsMapper;
    @Resource
    private OnlCgformButtonMapper onlCgformButtonMapper;
    @Resource
    private OnlCgformEnhanceJavaMapper onlCgformEnhanceJavaMapper;
    @Resource
    private OnlCgformEnhanceSqlMapper onlCgformEnhanceSqlMapper;
    @Autowired
    private DataBaseConfig dataBaseConfig;
    @Autowired
    @Lazy
    private DbReadTableUtil dbReadTableUtil;
    @Autowired
    private CodeGenerateOne codeGenerateOne;

    @Transactional(rollbackFor = {Exception.class})
    public Result<?> addAll(OnlCgformModel model) {
        String uuid = UUID.randomUUID().toString().replace("-", "");
        OnlCgformHead head = model.getHead();
        List<OnlCgformField> fields = model.getFields();
        List<OnlCgformIndex> indexs = model.getIndexs();
        head.setId(uuid);
        for (int i = 0; i < fields.size(); ++i) {
            OnlCgformField field = fields.get(i);
            field.setId(null);
            field.setCgformHeadId(uuid);
            if (field.getOrderNum() == null) {
                field.setOrderNum(i);
            }
        }
        for (OnlCgformIndex index : indexs) {
            index.setId(null);
            index.setCgformHeadId(uuid);
        }
        head.setIsDbSynch("N");
        head.setTableVersion(1);
        super.save(head);
        this.fieldService.saveBatch(fields);
        this.indexService.saveBatch(indexs);
        this.handleMainTableInfo(head, fields);
        return Result.ok("添加成功");
    }

    @Transactional(rollbackFor = Exception.class)
    public Result<?> editAll(OnlCgformModel model) {
        OnlCgformHead head = model.getHead();
        OnlCgformHead headEntity = super.getById(head.getId());
        if (headEntity == null) {
            return Result.error("未找到对应实体");
        } else {
            Integer version = headEntity.getTableVersion();
            if (version == null) {
                version = 1;
            }
            head.setTableVersion(version + 1);
            List<OnlCgformField> fields = model.getFields();
            List<OnlCgformIndex> indexs = model.getIndexs();
            List<OnlCgformField> addFields = new ArrayList<>();
            List<OnlCgformField> editFields = new ArrayList<>();
            for (OnlCgformField field : fields) {
                String id = String.valueOf(field.getId());
                if (id.length() == 32) {
                    editFields.add(field);
                } else {
                    String primaryKey = "_pk";
                    if (!primaryKey.equals(id)) {
                        field.setId(null);
                        field.setCgformHeadId(head.getId());
                        addFields.add(field);
                    }
                }
            }
            int maxOrderNum = 0;
            OnlCgformField onlCgformField;

            Iterator<OnlCgformField> var18;
            for (var18 = editFields.iterator(); var18.hasNext(); this.fieldService.updateById(onlCgformField)) {
                onlCgformField = var18.next();
                OnlCgformField dbField = this.fieldService.getById(onlCgformField.getId());
                if ((dbField.getOrderNum() == null ? 0 : dbField.getOrderNum()) > maxOrderNum) {
                    maxOrderNum = dbField.getOrderNum();
                }
            }

            for (var18 = addFields.iterator(); var18.hasNext(); this.fieldService.save(onlCgformField)) {
                onlCgformField = (OnlCgformField) var18.next();
                if (onlCgformField.getOrderNum() == null) {
                    ++maxOrderNum;
                    onlCgformField.setOrderNum(maxOrderNum);
                }
            }

            List<OnlCgformIndex> addIndex = new ArrayList<>();
            List<OnlCgformIndex> editIndex = new ArrayList<>();
            OnlCgformIndex index;
            for (OnlCgformIndex onlCgformIndex : indexs) {
                index = onlCgformIndex;
                String id = String.valueOf(index.getId());
                if (id.length() == 32) {
                    editIndex.add(index);
                } else {
                    index.setId(null);
                    index.setCgformHeadId(head.getId());
                    addIndex.add(index);
                }
            }
            this.indexService.saveBatch(addIndex);
            for (Iterator<OnlCgformIndex> var23 = editIndex.iterator(); var23.hasNext(); this.indexService.updateById(index)) {
                index = var23.next();
            }
            if (!model.getDeleteFieldIds().isEmpty()) {
                this.fieldService.removeByIds(model.getDeleteFieldIds());
            }
            if (!model.getDeleteIndexIds().isEmpty()) {
                this.indexService.removeByIds(model.getDeleteIndexIds());
            }
            //不论修改了什么，统统改成未同步
            head.setIsDbSynch("N");
            super.updateById(head);
            this.handleMainTableInfo(head, fields);
            return Result.ok("全部修改成功");
        }
    }

    public void doDbSynch(String code, String synMethod) throws HibernateException, IOException, SQLException, DBException, TemplateException {
        OnlCgformHead onlCgformHead = this.getById(code);
        if (onlCgformHead == null) {
            throw new DBException("实体配置不存在");
        } else {
            String tbname = onlCgformHead.getTableName();
            LambdaQueryWrapper<OnlCgformField> query = new LambdaQueryWrapper<>();
            query.eq(OnlCgformField::getCgformHeadId, code);
            query.orderByAsc(OnlCgformField::getOrderNum);
            List<OnlCgformField> fieldList = this.fieldService.list(query);
            CgformConfigModel model = new CgformConfigModel();
            model.setTableName(tbname);
            model.setJformPkType(onlCgformHead.getIdType());
            model.setJformPkSequence(onlCgformHead.getIdSequence());
            model.setContent(onlCgformHead.getTableTxt());
            model.setColumns(fieldList);
            model.setDbConfig(this.dataBaseConfig);
            if ("normal".equals(synMethod)) {
                boolean isExist = DbTableUtil.judgeTableIsExit(tbname);
                if (isExist) {
                    DbTableProcess process = new DbTableProcess();
                    List<String> list = process.updateTable(model);
                    for (String sql : list) {
                        if (!oConvertUtils.isEmpty(sql) && !oConvertUtils.isEmpty(sql.trim())) {
                            this.baseMapper.executeDDL(sql);
                        }
                    }
                    LambdaQueryWrapper<OnlCgformIndex> lqw = new LambdaQueryWrapper<>();
                    lqw.eq(OnlCgformIndex::getCgformHeadId, code);
                    List<OnlCgformIndex> configIndexList = this.indexService.list(lqw);
                    for (OnlCgformIndex configIndex : configIndexList) {
                        String delIndexSql = process.dropIndex(configIndex.getIndexName(), tbname);
                        this.baseMapper.executeDDL(delIndexSql);
                    }
                } else {
                    DbTableProcess.createTable(model);
                }
            } else if ("force".equals(synMethod)) {
                DbTableHandleI handler = DbTableUtil.getTableHandle();
                String sql = handler.dropTableSQL(tbname);
                this.baseMapper.executeDDL(sql);
                DbTableProcess.createTable(model);
            }

            this.indexService.createIndex(code, DbTableUtil.getDatabaseType(), tbname);
            onlCgformHead.setIsDbSynch("Y");
            this.updateById(onlCgformHead);
        }
    }

    public void deleteRecordAndTable(String id, boolean isdelrecord) throws DBException {
        OnlCgformHead onlCgformHead = this.getById(id);
        if (onlCgformHead == null) {
            throw new DBException("实体配置不存在");
        } else {
            if (isdelrecord) {
                this.baseMapper.deleteById(id);
            }
        }
    }

    public List<Map<String, Object>> queryListData(String sql) {
        return this.baseMapper.queryList(sql);
    }

    public void saveEnhance(OnlCgformEnhanceJs onlCgformEnhanceJs) {
        this.onlCgformEnhanceJsMapper.insert(onlCgformEnhanceJs);
    }

    public OnlCgformEnhanceJs queryEnhance(String code, String type) {
        return this.onlCgformEnhanceJsMapper.selectOne(((new LambdaQueryWrapper<OnlCgformEnhanceJs>()).eq(OnlCgformEnhanceJs::getCgJsType, type)).eq(OnlCgformEnhanceJs::getCgformHeadId, code));
    }

    public void editEnhance(OnlCgformEnhanceJs onlCgformEnhanceJs) {
        this.onlCgformEnhanceJsMapper.updateById(onlCgformEnhanceJs);
    }

    public OnlCgformEnhanceSql queryEnhanceSql(String formId, String buttonCode) {
        return (OnlCgformEnhanceSql) this.onlCgformEnhanceSqlMapper.selectOne(((new LambdaQueryWrapper<OnlCgformEnhanceSql>()).eq(OnlCgformEnhanceSql::getCgformHeadId, formId)).eq(OnlCgformEnhanceSql::getButtonCode, buttonCode));
    }

    public void saveEnhance(OnlCgformEnhanceSql onlCgformEnhanceSql) {
        this.onlCgformEnhanceSqlMapper.insert(onlCgformEnhanceSql);
    }

    public void editEnhance(OnlCgformEnhanceSql onlCgformEnhanceSql) {
        this.onlCgformEnhanceSqlMapper.updateById(onlCgformEnhanceSql);
    }

    public OnlCgformEnhanceJava queryEnhanceJava(OnlCgformEnhanceJava onlCgformEnhanceJava) {
        return this.onlCgformEnhanceJavaMapper.selectOne(new LambdaQueryWrapper<OnlCgformEnhanceJava>().eq(OnlCgformEnhanceJava::getButtonCode, onlCgformEnhanceJava.getButtonCode()).eq(OnlCgformEnhanceJava::getCgformHeadId, onlCgformEnhanceJava.getCgformHeadId()).eq(OnlCgformEnhanceJava::getCgJavaType, onlCgformEnhanceJava.getCgJavaType()).eq(OnlCgformEnhanceJava::getEvent, onlCgformEnhanceJava.getEvent()));
    }

    public void saveEnhance(OnlCgformEnhanceJava onlCgformEnhanceJava) {
        this.onlCgformEnhanceJavaMapper.insert(onlCgformEnhanceJava);
    }

    public void editEnhance(OnlCgformEnhanceJava onlCgformEnhanceJava) {
        this.onlCgformEnhanceJavaMapper.updateById(onlCgformEnhanceJava);
    }

    public List<OnlCgformButton> queryButtonList(String code, boolean isListButton) {
        LambdaQueryWrapper<OnlCgformButton> queryWrapper = new LambdaQueryWrapper<OnlCgformButton>().eq(OnlCgformButton::getButtonStatus, "1").eq(OnlCgformButton::getCgformHeadId, code);
        if (isListButton) {
            queryWrapper.in(OnlCgformButton::getButtonStyle, "link", "button");
        } else {
            queryWrapper.eq(OnlCgformButton::getButtonStyle, "form");
        }
        queryWrapper.orderByAsc(OnlCgformButton::getOrderNum);
        return this.onlCgformButtonMapper.selectList(queryWrapper);
    }

    public List<OnlCgformButton> queryButtonList(String code) {
        return this.onlCgformButtonMapper.selectList(new LambdaQueryWrapper<OnlCgformButton>().eq(OnlCgformButton::getButtonStatus, "1").eq(OnlCgformButton::getCgformHeadId, code).orderByAsc(OnlCgformButton::getOrderNum));
    }

    public boolean checkOnlyEnhance(OnlCgformEnhanceJava onlCgformEnhanceJava) {
        long count = this.onlCgformEnhanceJavaMapper.selectCount(new LambdaQueryWrapper<OnlCgformEnhanceJava>().eq(OnlCgformEnhanceJava::getButtonCode, onlCgformEnhanceJava.getButtonCode()).eq(OnlCgformEnhanceJava::getCgformHeadId, onlCgformEnhanceJava.getCgformHeadId()).eq(OnlCgformEnhanceJava::getCgJavaType, onlCgformEnhanceJava.getCgJavaType()).eq(OnlCgformEnhanceJava::getEvent, onlCgformEnhanceJava.getEvent()));
        if (count == 1 && oConvertUtils.isEmpty(onlCgformEnhanceJava.getId())) {
            return false;
        }
        return count != 2;
    }

    public List<String> queryOnlinetables() {
        return this.baseMapper.queryOnlinetables();
    }

    @Transactional(rollbackFor = {Exception.class})
    public void saveDbTable2Online(String tbname) {
        OnlCgformHead cgFormHead = new OnlCgformHead();
        cgFormHead.setTableType(1);
        cgFormHead.setIsCheckbox("Y");
        cgFormHead.setIsDbSynch("Y");
        cgFormHead.setIsTree("N");
        cgFormHead.setIsPage("Y");
        cgFormHead.setQueryMode("group");
        cgFormHead.setTableName(tbname.toLowerCase());
        cgFormHead.setTableTxt(tbname);
        cgFormHead.setTableVersion(1);
        cgFormHead.setFormTemplate("1");
        String cgFormId = UUIDGenerator.generate();
        cgFormHead.setId(cgFormId);
        List<OnlCgformField> columnsList = new ArrayList<>();
        try {
            List<ColumnVo> list = dbReadTableUtil.b(tbname);
            for (int k = 0; k < list.size(); ++k) {
                ColumnVo columnVo = list.get(k);
                log.info("  columnVo : {}", columnVo.toString());
                String fieldName = columnVo.getFieldDbName();
                OnlCgformField cgFormField = new OnlCgformField();
                cgFormField.setCgformHeadId(cgFormId);
                cgFormField.setDbFieldNameOld(columnVo.getFieldDbName().toLowerCase());
                cgFormField.setDbFieldName(columnVo.getFieldDbName().toLowerCase());
                if (oConvertUtils.isNotEmpty(columnVo.getFiledComment())) {
                    cgFormField.setDbFieldTxt(columnVo.getFiledComment());
                } else {
                    cgFormField.setDbFieldTxt(columnVo.getFieldName());
                }

                cgFormField.setDbIsKey(0);
                cgFormField.setIsShowForm(1);
                cgFormField.setIsQuery(0);
                cgFormField.setFieldMustInput("0");
                cgFormField.setIsShowList(1);
                cgFormField.setOrderNum(k + 1);
                cgFormField.setQueryMode("group");
                cgFormField.setDbLength(oConvertUtils.getInt(columnVo.getPrecision()));
                cgFormField.setFieldLength(120);
                cgFormField.setDbPointLength(oConvertUtils.getInt(columnVo.getScale()));
                cgFormField.setFieldShowType("text");
                cgFormField.setDbIsNull("Y".equals(columnVo.getNullable()) ? 1 : 0);
                if ("id".equalsIgnoreCase(fieldName)) {
                    String[] pkTypeArr = new String[]{"java.lang.Integer", "java.lang.Long"};
                    String idFiledType = columnVo.getFieldType();
                    if (Arrays.asList(pkTypeArr).contains(idFiledType)) {
                        cgFormHead.setIdType("NATIVE");
                    } else {
                        cgFormHead.setIdType("UUID");
                    }

                    cgFormField.setDbIsKey(1);
                    cgFormField.setIsShowForm(0);
                    cgFormField.setIsShowList(0);
                }

                if ("java.lang.Integer".equalsIgnoreCase(columnVo.getFieldType())) {
                    cgFormField.setDbType("int");
                } else if ("java.lang.Long".equalsIgnoreCase(columnVo.getFieldType())) {
                    cgFormField.setDbType("int");
                } else if ("java.util.Date".equalsIgnoreCase(columnVo.getFieldType())) {
                    cgFormField.setDbType("Date");
                    cgFormField.setFieldShowType("date");
                } else if (!"java.lang.Double".equalsIgnoreCase(columnVo.getFieldType()) && !"java.lang.Float".equalsIgnoreCase(columnVo.getFieldType())) {
                    if (!"java.math.BigDecimal".equalsIgnoreCase(columnVo.getFieldType()) && !"BigDecimal".equalsIgnoreCase(columnVo.getFieldType())) {
                        if (!"byte[]".equalsIgnoreCase(columnVo.getFieldType()) && !columnVo.getFieldType().contains("blob")) {
                            cgFormField.setDbType("string");
                        } else {
                            cgFormField.setDbType("Blob");
                            columnVo.setCharmaxLength(null);
                        }
                    } else {
                        cgFormField.setDbType("BigDecimal");
                    }
                } else {
                    cgFormField.setDbType("double");
                }

                if (oConvertUtils.isEmpty(columnVo.getPrecision()) && oConvertUtils.isNotEmpty(columnVo.getCharmaxLength())) {
                    if (Long.parseLong(columnVo.getCharmaxLength()) >= 3000L) {
                        cgFormField.setDbType("Text");
                        cgFormField.setFieldShowType("textarea");

                        try {
                            cgFormField.setDbLength(Integer.valueOf(columnVo.getCharmaxLength()));
                        } catch (Exception var12) {
                            log.error(var12.getMessage(), var12);
                        }
                    } else {
                        cgFormField.setDbLength(Integer.valueOf(columnVo.getCharmaxLength()));
                    }
                } else {
                    if (oConvertUtils.isNotEmpty(columnVo.getPrecision())) {
                        cgFormField.setDbLength(Integer.valueOf(columnVo.getPrecision()));
                    } else if (cgFormField.getDbType().equals("int")) {
                        cgFormField.setDbLength(10);
                    }

                    if (oConvertUtils.isNotEmpty(columnVo.getScale())) {
                        cgFormField.setDbPointLength(Integer.valueOf(columnVo.getScale()));
                    }
                }
                columnsList.add(cgFormField);
            }
        } catch (Exception var13) {
            log.error(var13.getMessage(), var13);
        }

        if (oConvertUtils.isEmpty(cgFormHead.getFormCategory())) {
            cgFormHead.setFormCategory("bdfl_include");
        }

        this.save(cgFormHead);
        this.fieldService.saveBatch(columnsList);
    }

    private void handleMainTableInfo(OnlCgformHead head, List<OnlCgformField> fields) {
        if (head.getTableType() != 3) {
            return;
        }
        head = this.baseMapper.selectById(head.getId());
        for (OnlCgformField onlCgformField : fields) {
            String tbName = onlCgformField.getMainTable();
            if (oConvertUtils.isEmpty(tbName)) {
                continue;
            }
            OnlCgformHead mainTable = this.baseMapper.selectOne((new LambdaQueryWrapper<OnlCgformHead>()).eq(OnlCgformHead::getTableName, tbName));
            if (mainTable == null) {
                continue;
            }
            String allSubTable = mainTable.getSubTableStr();
            if (oConvertUtils.isEmpty(allSubTable)) {
                allSubTable = head.getTableName();
            } else if (!allSubTable.contains(head.getTableName())) {
                List<String> arr = new ArrayList<>(Arrays.asList(allSubTable.split(",")));
                for (int k = 0; k < arr.size(); ++k) {
                    String tempTbname = arr.get(k);
                    OnlCgformHead tempTable = this.baseMapper.selectOne((new LambdaQueryWrapper<OnlCgformHead>()).eq(OnlCgformHead::getTableName, tempTbname));
                    if (tempTable != null && head.getTabOrderNum() < tempTable.getTabOrderNum()) {
                        arr.add(k, head.getTableName());
                        break;
                    }
                }
                if (!arr.contains(head.getTableName())) {
                    arr.add(head.getTableName());
                }
                allSubTable = String.join(",", arr);
            }
            mainTable.setSubTableStr(allSubTable);
            this.baseMapper.updateById(mainTable);
            break;
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void saveManyFormData(String code, JSONObject json) throws DBException, BusinessException {
        OnlCgformHead head = this.getById(code);
        if (head == null) {
            throw new DBException("数据库主表ID[" + code + "]不存在");
        }
        String currButtonCode = "add";
        this.executeEnhanceJava(currButtonCode, "start", head, json);
        json.put("id", UUIDGenerator.generate());
        String tbname = head.getTableName();
        if (head.getTableType() == 2) {
            String subTables = head.getSubTableStr();
            String[] arr = subTables.split(",");
            for (String tb : arr) {
                JSONArray jsonArray = json.getJSONArray(tb);
                if (jsonArray != null && !jsonArray.isEmpty()) {
                    OnlCgformHead temp = this.baseMapper.selectOne((new LambdaQueryWrapper<OnlCgformHead>()).eq(OnlCgformHead::getTableName, tb));
                    if (temp != null) {
                        List<OnlCgformField> subFieldList = this.fieldService.list((new LambdaQueryWrapper<OnlCgformField>()).eq(OnlCgformField::getCgformHeadId, temp.getId()));
                        String sublinkField = "";
                        String subLinkValue = null;
                        for (OnlCgformField field : subFieldList) {
                            if (!oConvertUtils.isEmpty(field.getMainField())) {
                                sublinkField = field.getDbFieldName();
                                String mainField = field.getMainField();
                                subLinkValue = json.getString(mainField);
                            }
                        }
                        for (int i = 0; i < jsonArray.size(); ++i) {
                            JSONObject jsonObject = jsonArray.getJSONObject(i);
                            if (subLinkValue != null) {
                                jsonObject.put(sublinkField, subLinkValue);
                            }
                            this.fieldService.saveFormData(subFieldList, tb, jsonObject);
                        }
                    }
                }
            }
        }

        this.fieldService.saveFormData(code, tbname, json);
        this.executeEnhanceSql(currButtonCode, code, json);
        this.executeEnhanceJava(currButtonCode, "end", head, json);
    }

    public Map<String, Object> queryManyFormData(String code, String id) throws DBException {
        OnlCgformHead head = (OnlCgformHead) this.getById(code);
        if (head == null) {
            throw new DBException("数据库主表ID[" + code + "]不存在");
        }
        List<OnlCgformField> fieldList = this.fieldService.queryFormFields(code, true);
        Map<String, Object> map = this.fieldService.queryFormData(fieldList, head.getTableName(), id);
        if (head.getTableType() == 2) {
            String subTables = head.getSubTableStr();
            String[] arr = subTables.split(",");
            for (String tb : arr) {
                OnlCgformHead temp = (OnlCgformHead) ((OnlCgformHeadMapper) this.baseMapper).selectOne((new LambdaQueryWrapper<OnlCgformHead>()).eq(OnlCgformHead::getTableName, tb));
                if (temp != null) {
                    List<OnlCgformField> subFieldList = this.fieldService.queryFormFields(temp.getId(), false);
                    String sublinkField = "";
                    String subLinkValue = null;
                    for (OnlCgformField field : subFieldList) {
                        if (!oConvertUtils.isEmpty(field.getMainField())) {
                            sublinkField = field.getDbFieldName();
                            String mainField = field.getMainField();
                            subLinkValue = map.get(mainField).toString();
                        }
                    }
                    List<Map<String, Object>> subList = this.fieldService.querySubFormData(subFieldList, tb, sublinkField, subLinkValue);
                    if (subList != null && !subList.isEmpty()) {
                        map.put(tb, subList);
                    } else {
                        map.put(tb, new String[0]);
                    }
                }
            }
        }
        return map;
    }

    @Transactional(rollbackFor = Exception.class)
    public void editManyFormData(String code, JSONObject json) throws DBException, BusinessException {
        OnlCgformHead head = this.getById(code);
        if (head == null) {
            throw new DBException("数据库主表ID[" + code + "]不存在");
        }
        String currButtonCode = "edit";
        this.executeEnhanceJava(currButtonCode, "start", head, json);
        String tbname = head.getTableName();
        this.fieldService.editFormData(code, tbname, json);
        if (head.getTableType() == 2) {
            String subTables = head.getSubTableStr();
            String[] arr = subTables.split(",");
            for (String tb : arr) {
                OnlCgformHead temp = this.baseMapper.selectOne((new LambdaQueryWrapper<OnlCgformHead>()).eq(OnlCgformHead::getTableName, tb));
                if (temp != null) {
                    List<OnlCgformField> subFieldList = this.fieldService.list((new LambdaQueryWrapper<OnlCgformField>()).eq(OnlCgformField::getCgformHeadId, temp.getId()));
                    String sublinkField = "";
                    String subLinkValue = null;
                    for (OnlCgformField field : subFieldList) {
                        if (!oConvertUtils.isEmpty(field.getMainField())) {
                            sublinkField = field.getDbFieldName();
                            String mainField = field.getMainField();
                            subLinkValue = json.getString(mainField);
                        }
                    }
                    if (!oConvertUtils.isEmpty(subLinkValue)) {
                        this.fieldService.deleteAutoList(tb, sublinkField, subLinkValue);
                        JSONArray jsonArray = json.getJSONArray(tb);
                        if (jsonArray != null && !jsonArray.isEmpty()) {
                            for (int i = 0; i < jsonArray.size(); ++i) {
                                JSONObject jsonObject = jsonArray.getJSONObject(i);
                                jsonObject.put(sublinkField, subLinkValue);
                                this.fieldService.saveFormData(subFieldList, tb, jsonObject);
                            }
                        }
                    }
                }
            }
        }

        this.executeEnhanceJava(currButtonCode, "end", head, json);
        this.executeEnhanceSql(currButtonCode, code, json);
    }

    /**
     * 执行增强JAVA
     *
     * @param buttonCode 按钮编码
     * @param eventType  事件类型
     * @param head       表单对象
     * @param json       表单数据
     * @throws BusinessException 异常
     */
    public void executeEnhanceJava(String buttonCode, String eventType, OnlCgformHead head, JSONObject json) throws BusinessException {
        OnlCgformEnhanceJava enhance = this.onlCgformEnhanceJavaMapper.selectOne(new LambdaQueryWrapper<OnlCgformEnhanceJava>().eq(OnlCgformEnhanceJava::getActiveStatus, "1").eq(OnlCgformEnhanceJava::getButtonCode, buttonCode).eq(OnlCgformEnhanceJava::getCgformHeadId, head.getId()).eq(OnlCgformEnhanceJava::getEvent, eventType));
        if (enhance == null) {
            return;
        }
        String javaType = enhance.getCgJavaType();
        String javaValue = enhance.getCgJavaValue();
        if (oConvertUtils.isEmpty(javaValue)) {
            return;
        }
        Object obj = null;
        if ("class".equals(javaType)) {
            try {
                Class<?> aClass = MyClassLoader.getClassByScn(javaValue);
                obj = aClass.newInstance();
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        } else if ("spring".equals(javaType)) {
            obj = SpringContextUtils.getBean(javaValue);
        }
        if (obj instanceof CgformEnhanceJavaInter javaInter) {
            javaInter.execute(head.getTableName(), json);
        }
    }

    /**
     * 执行增强sql
     *
     * @param buttonCode 按钮code
     * @param formId     表单id
     * @param json       表单数据
     */
    public void executeEnhanceSql(String buttonCode, String formId, JSONObject json) {
        OnlCgformEnhanceSql enhance = this.onlCgformEnhanceSqlMapper.selectOne(new LambdaQueryWrapper<OnlCgformEnhanceSql>().eq(OnlCgformEnhanceSql::getButtonCode, buttonCode).eq(OnlCgformEnhanceSql::getCgformHeadId, formId));
        if (enhance == null) {
            return;
        }
        String formateSQl = CgformUtil.formateSQl(enhance.getCgbSql(), json);
        String[] arr = formateSQl.split(";");
        for (String sql : arr) {
            if (Strings.isBlank(sql)) {
                continue;
            }
            this.baseMapper.executeDDL(sql);
        }
    }

    public void executeCustomerButton(String buttonCode, String formId, String dataId) throws BusinessException {
        OnlCgformHead head = (OnlCgformHead) this.getById(formId);
        if (head == null) {
            throw new BusinessException("未找到表配置信息");
        } else {
            Map<String, Object> data = this.baseMapper.queryOneByTableNameAndId(head.getTableName(), dataId);
            JSONObject json = JSONObject.parseObject(JSON.toJSONString(data));
            this.executeEnhanceJava(buttonCode, "start", head, json);
            this.executeEnhanceSql(buttonCode, formId, json);
            this.executeEnhanceJava(buttonCode, "end", head, json);
        }
    }


    public OnlCgformEnhanceJs queryEnhanceJs(String formId, String cgJsType) {
        return this.onlCgformEnhanceJsMapper.selectOne(new LambdaQueryWrapper<OnlCgformEnhanceJs>().eq(OnlCgformEnhanceJs::getCgformHeadId, formId).eq(OnlCgformEnhanceJs::getCgJsType, cgJsType));
    }

    public void deleteOneTableInfo(String formId, String dataId) throws BusinessException {
        OnlCgformHead head = this.getById(formId);
        if (head == null) {
            throw new BusinessException("未找到表配置信息");
        } else {
            Map<String, Object> record = this.baseMapper.queryOneByTableNameAndId(head.getTableName(), dataId);
            if (record == null) {
                throw new BusinessException("未找到数据信息");
            } else {
                String buttonCode = "delete";
                JSONObject json = JSONObject.parseObject(JSON.toJSONString(record));
                this.executeEnhanceJava(buttonCode, "start", head, json);
                String sql = "delete from " + head.getTableName() + " where id = '" + dataId + "'";
                this.baseMapper.deleteOne(sql);
                this.executeEnhanceSql(buttonCode, formId, json);
                this.executeEnhanceJava(buttonCode, "end", head, json);
            }
        }
    }

    public JSONObject queryFormItem(OnlCgformHead head) {
        List<OnlCgformField> fieldList = this.fieldService.queryAvailableFields(head.getId(), head.getTableName(), false);
        List<String> disabledFieldNameList = this.fieldService.queryDisabledFields(head.getTableName());
        JSONObject schema = CgformUtil.getJsonSchemaByCgformFieldList(fieldList, disabledFieldNameList);
        if (head.getTableType() == 2) {
            String subStr = head.getSubTableStr();
            if (oConvertUtils.isNotEmpty(subStr)) {
                String[] var6 = subStr.split(",");
                for (String tbname : var6) {
                    OnlCgformHead tempTable = this.baseMapper.selectOne((new LambdaQueryWrapper<OnlCgformHead>()).eq(OnlCgformHead::getTableName, tbname));
                    if (tempTable != null) {
                        List<OnlCgformField> subFieldList = this.fieldService.queryAvailableFields(tempTable.getId(), tempTable.getTableName(), false);
                        JSONObject subJson = new JSONObject();
                        subJson.put("columns", CgformUtil.getJEditableTableColumnsJson(subFieldList));
                        subJson.put("describe", tempTable.getTableTxt());
                        subJson.put("key", tempTable.getTableName());
                        subJson.put("view", "tab");
                        schema.getJSONObject("properties").put(tempTable.getTableName(), subJson);
                    }
                }
            }
        }

        return schema;
    }

    /**
     * 生成代码
     **/
    public void generateCode(OnlGenerateModel onlGenerateModel) throws Exception {
        TableVo tableVo = new TableVo();
        tableVo.setEntityName(onlGenerateModel.getEntityName());
        tableVo.setEntityPackage(onlGenerateModel.getEntityPackage());
        tableVo.setFtlDescription(onlGenerateModel.getFtlDescription());
        tableVo.setTableName(onlGenerateModel.getTableName());
        tableVo.setSearchFieldNum(-1);
        List<ColumnVo> columns = new ArrayList<>();
        List<ColumnVo> originalColumns = new ArrayList<>();
        this.initColumnVoList(onlGenerateModel.getCode(), columns, originalColumns);
        codeGenerateOne.generateCodeFile(onlGenerateModel, tableVo, columns, originalColumns);
    }

    /**
     * 初始化列信息
     **/
    private void initColumnVoList(String cgformHeadId, List<ColumnVo> columns, List<ColumnVo> originalColumns) {
        List<OnlCgformField> fieldList = this.fieldService.list(new LambdaQueryWrapper<OnlCgformField>()
                .eq(OnlCgformField::getCgformHeadId, cgformHeadId)
                .orderByAsc(OnlCgformField::getOrderNum)
        );
        for (OnlCgformField onlCgformField : fieldList) {
            ColumnVo columnVo = new ColumnVo();
            columnVo.setFieldLength(onlCgformField.getFieldLength());
            columnVo.setFieldHref(onlCgformField.getFieldHref());
            columnVo.setFieldValidType(onlCgformField.getFieldValidType());
            columnVo.setFieldDefault(onlCgformField.getDbDefaultVal());
            columnVo.setFieldShowType(onlCgformField.getFieldShowType());
            columnVo.setFieldOrderNum(onlCgformField.getOrderNum());
            columnVo.setIsKey(onlCgformField.getDbIsKey() == 1 ? "Y" : "N");
            columnVo.setIsShow(onlCgformField.getIsShowForm() == 1 ? "Y" : "N");
            columnVo.setIsShowList(onlCgformField.getIsShowList() == 1 ? "Y" : "N");
            columnVo.setIsQuery(onlCgformField.getIsQuery() == 1 ? "Y" : "N");
            columnVo.setQueryMode(onlCgformField.getQueryMode());
            columnVo.setDictField(onlCgformField.getDictField());
            columnVo.setDictTable(onlCgformField.getDictTable());
            columnVo.setDictText(onlCgformField.getDictText());
            columnVo.setFieldDbName(onlCgformField.getDbFieldName());
            columnVo.setFieldName(oConvertUtils.camelName(onlCgformField.getDbFieldName()));
            columnVo.setFiledComment(onlCgformField.getDbFieldTxt());
            columnVo.setFieldDbType(onlCgformField.getDbType());
            columnVo.setFieldType(this.getFiledType(onlCgformField.getDbType()));
            columnVo.setClassType(onlCgformField.getFieldShowType());
            columnVo.setClassType_row(onlCgformField.getFieldShowType());
            if ("0".equals(onlCgformField.getFieldMustInput())) {
                columnVo.setNullable("Y");
            } else {
                columnVo.setNullable("N");
            }
            columnVo.setCharmaxLength(onlCgformField.getDbLength().toString());
            columnVo.setPrecision(onlCgformField.getDbPointLength().toString());
            System.out.println("columnVo = " + columnVo);
            originalColumns.add(columnVo);
            columns.add(columnVo);
        }

    }

    private String getFiledType(String dbType) {
        dbType = dbType.toLowerCase();
        if (dbType.contains("int")) {
            return "java.lang.Integer";
        } else if (dbType.contains("double")) {
            return "java.lang.Double";
        } else if (dbType.contains("decimal")) {
            return "java.math.BigDecimal";
        } else {
            return dbType.contains("date") ? "java.util.Date" : "java.lang.String";
        }
    }
}
